package org.budo.dubbo.protocol.http.sign;

import org.budo.dubbo.protocol.http.exception.consumer.AppSecretRequiredException;
import org.budo.dubbo.protocol.http.exception.consumer.ConsumerSideRuntimeException;
import org.budo.dubbo.protocol.http.util.BudoBeanUtil;
import org.budo.support.lang.util.StringUtil;
import org.springframework.util.Assert;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.Invocation;

import lombok.Getter;
import lombok.Setter;

/**
 * @author lmw
 */
@Getter
@Setter
public class DefaultSignCheckService extends AbstractSignCheckService {
    private String appKey;

    private String appSecret;

    public DefaultSignCheckService() {
    }

    public DefaultSignCheckService(String appKey, String appSecret) {
        this();

        this.setAppKey(appKey);
        this.setAppSecret(appSecret);
    }

    /**
     * 默认实现，建议覆盖
     */
    @Override
    public String getAppKey(Invocation invocation) {
        if (!StringUtils.isEmpty(this.appKey)) {
            return this.appKey;
        }

        DefaultSignCheckService budoSignCheckService = this.getBudoSignCheckService();
        if (budoSignCheckService.equals(this)) {
            throw new RuntimeException("#36 请覆盖这个方法 " + this + "#getAppKey");
        }

        String appKey = budoSignCheckService.getAppKey(invocation);

        if (StringUtils.isEmpty(appKey)) {
            String message = "#122 appKey required" //
                    + ", appKey=" + appKey //
                    + ", budoSignCheckService=" + budoSignCheckService;
            throw new ConsumerSideRuntimeException(message);
        }

        return appKey;
    }

    /**
     * 默认实现，建议覆盖
     */
    public String getAppSecret(String appKey) {
        if (!StringUtils.isEmpty(this.appSecret)) {
            return this.appSecret;
        }

        Assert.hasText(appKey, "#96 appKey can not be null, appKey=" + appKey);

        DefaultSignCheckService budoSignCheckService = this.getBudoSignCheckService();
        if (budoSignCheckService.equals(this) || StringUtil.equals(this.toString(), budoSignCheckService.toString())) {
            throw new RuntimeException("#64 conf the field appSecret, or override this method " + this.getClass().getName() + "#getAppSecret" + ", this=" + this);
        }

        String appSecret = budoSignCheckService.getAppSecret(appKey);

        if (StringUtils.isEmpty(appSecret)) {
            throw new AppSecretRequiredException(appKey);
        }

        return appSecret;
    }

    private DefaultSignCheckService getBudoSignCheckService() {
        DefaultSignCheckService budoSignCheckService = (DefaultSignCheckService) BudoBeanUtil.getBeanCached(DefaultSignCheckService.class, null);

        if (null == budoSignCheckService) {
            String message = "#139 budoSignCheckService required, this=" + this;
            throw new ConsumerSideRuntimeException(message);
        }

        return budoSignCheckService;
    }

    @Override
    public String toString() {
        return super.toString() + ", AppKey=" + this.getAppKey();
    }
}